#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import ConfigParser
from subprocess import PIPE, Popen
import pygtk
pygtk.require('2.0')
import gtk
import gtk.glade
import urllib2
import ast

ON_POSIX = 'posix' in sys.builtin_module_names
#import json

"""
login screen
"""

class MessageBox(gtk.Dialog):
    def __init__(self, message = "", buttons = [], pixmap = None, modal = gtk.TRUE):
        gtk.Dialog.__init__(self)
        self.connect("destroy", self.quit)
        self.connect("delete_event", self.quit)
        if modal:
            self.set_modal(gtk.TRUE)
        hbox = gtk.HBox(spacing=5)
        hbox.set_border_width(5)
        self.vbox.pack_start(hbox)
        hbox.show()

        if pixmap:
            self.realize()
            pixmap = Pixmap(self, pixmap)
            hbox.pack_start(pixmap, expand=gtk.FALSE)
            pixmap.show()

        label = gtk.Label(message)
        hbox.pack_start(label)
        label.show()

        for text in buttons:
            print text
            b = gtk.Button(text)
            b.set_flags(gtk.CAN_DEFAULT)
            b.set_data("user_data", text)
            b.connect("clicked", self.click)
            self.action_area.pack_start(b)
            b.show()

        self.ret = None

    def quit(self, *args):
        self.hide()
        self.destroy()

    def click(self, button):
        self.ret = button.get_data("user_data")
        self.quit()

class LoginApp:
    """Login App"""
    workdir = os.path.dirname(os.path.realpath(__file__))

    pngfilename = os.path.join(workdir, "welcome2.jpg")
    savedfilename = os.path.join(workdir, "login.txt")
    gladefilename = os.path.join(workdir, "login.glade")

    def get_resolution(self):
        display = gtk.gdk.display_get_default()
        screen = display.get_default_screen()
        return (screen.get_height(), screen.get_width());

    def loadsavedusername(self):
        config = ConfigParser.RawConfigParser();
        config.read(self.savedfilename);

        try:
            if config.getboolean('login', 'remember'):
                self.entryuser.set_text(config.get('login','user'))
                self.entrypass.set_text(config.get('login', 'password'))
            self.toggleremember.set_active(config.getboolean('login', 'remember'))
            self.getvmUrl = config.get('login', 'graburl')
            self.loginbutton.grab_focus()
        except:
            pass

    def __init__(self):
        self.dic = {"on_LoginWindow_destroy" : gtk.main_quit
            ,"on_buttonLogin_clicked" : self.OnLogin
            ,"on_buttonSetup_clicked" : self.OnSetup
            ,"on_buttonClean_clicked" : self.OnClean
            ,"on_buttonDialogSave_clicked" : self.OnSaveConfig
            ,"on_buttonDialogCancel_clicked" : self.OnCancelConfig
            ,"on_checkbuttonRemember_toggled" : self.OnRemember
            ,"on_combox_changed" : self.OnComboboxchanged
            ,"on_radiobutton_changed" : self.OnRadiobuttonChanged
            ,"on_switch_notebook" : self.OnPageChanged
            ,"on_button_test_ping_clicked":self.OnTestPingClicked
            ,"on_button_server_ok_clicked":self.OnSaveServerClicked};

        self.logintree = gtk.glade.XML(self.gladefilename, "LoginWindow");

        self.logintree.signal_autoconnect(self.dic);
        self.loginwindow = self.logintree.get_widget("LoginWindow");
        #self.loginwindow.set_position(gtk.WIN_POS_CENTER)
        self.loginwindow.fullscreen()
        (height, width) = self.get_resolution();
        print "Resolution:", width, "x", height
        self.loginwindow.move(0,0);
        self.loginwindow.resize(width,height);
        #self.loginwindow.show_all();
        self.pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(self.pngfilename, width, height)
        #self.pixbuf = gtk.gdk.pixbuf_new_from_file(self.pngfilename)
        #self.pixbuf.scale_simple(width, height, gtk.gdk.INTERP_HYPER)
        #print self.pixbuf.get_width(), 'x', self.pixbuf.get_height()
        self.bimage = self.logintree.get_widget("imageBackground");
        self.bimage.set_size_request(width, height);
        self.bimage.set_from_pixbuf(self.pixbuf);
        self.lframe = self.logintree.get_widget("frameMain");
        framewidth, frameheight = self.lframe.get_size_request();
        #print framewidth, frameheight;
        self.lframe.set_uposition((width - framewidth) / 2,
        (height - frameheight) / 2);

        self.entryuser = self.logintree.get_widget("entryUser");
        self.comboVms = self.logintree.get_widget("comboVms");
        self.entrypass = self.logintree.get_widget("entryPassword");
        self.toggleremember = self.logintree.get_widget("checkbuttonRemember")
        self.loginbutton = self.logintree.get_widget("buttonLogin");

        self.loadsavedusername();

        self.dialogtree = gtk.glade.XML(self.gladefilename, "windowSetup");
        self.setupwindow = self.dialogtree.get_widget("windowSetup");
        self.dialogtree.signal_autoconnect(self.dic);
        self.logintree.get_widget('label1').modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('white'))
        self.logintree.get_widget('label2').modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('white'))
        self.logintree.get_widget('label3').modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('white'))
        #self.toggleremember.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('white'))


    def OnLogin(self, widget):
        self.comboVms.set_model(None)
        self.comboVms.clear()
        try:
            user, passwd = self.entryuser.get_text(), self.entrypass.get_text()
            self.OnRemember(self.toggleremember)
            #postdata = {"name": user, "password":passwd}
            #request = urllib2.Request(self.getvmUrl, data=json.dumps(postdata))
            url = self.getvmUrl+"?name=%s&password=%s"%(user, passwd)
            request = urllib2.Request(url)
            respone = urllib2.urlopen(request)
            _vms = respone.read()
            if _vms == "0":
                self.alert('密码错误')
                return
            _vms = ast.literal_eval(_vms)
        except ValueError:
            self.alert('服务端响应数据错误')
            return
        except:
            self.alert('网络无响应')
            return
        self.vms = [('请选择', '', "0", "")]
        self.vms += _vms
        self.comboVms.clear()
        liststore = gtk.ListStore(str, str, str, str)
        for item in self.vms:
            liststore.append(item)
        cell = gtk.CellRendererText()
        self.comboVms.set_model(liststore)
        self.comboVms.pack_start(cell, True)
        self.comboVms.add_attribute(cell, 'text', 0)
        self.comboVms.set_active(0)

    def OnSetup(self, widget):
        if os.path.isfile('/etc/network/interfaces'):
            self.dialogtree.get_widget('radiobuttonDhcp').set_active(True)
            #self.dialogtree.get_widget('entryDialogIP').set_editable(False)
            #self.dialogtree.get_widget('entryDialogNetmask').set_editable(False)
            #self.dialogtree.get_widget('entryDialogGateway').set_editable(False)
            f = open('/etc/network/interfaces', 'r')
            line = f.readline()
            while line:
                line = line.lower()
                if line.startswith('iface') and line.endswith('static\n'):
                    self.dialogtree.get_widget('radiobuttonStaticIP').set_active(True)
                    #self.dialogtree.get_widget('entryDialogIP').set_editable(True)
                    #self.dialogtree.get_widget('entryDialogNetmask').set_editable(True)
                    #self.dialogtree.get_widget('entryDialogGateway').set_editable(True)
                elif line.startswith("address"):
                    self.dialogtree.get_widget('entryDialogIP').set_text(line.split()[1])
                elif line.startswith("netmask"):
                    self.dialogtree.get_widget('entryDialogNetmask').set_text(line.split()[1])
                elif line.startswith("gateway"):
                    self.dialogtree.get_widget('entryDialogGateway').set_text(line.split()[1])
                line = f.readline()
            f.close()
        else:
            self.dialogtree.get_widget('radiobuttonDhcp').set_active(True)
        if os.path.isfile('/etc/resolv.conf'):
            self.dialogtree.get_widget('radiobuttonDNS').set_active(True)
            #self.dialogtree.get_widget('entryDNS1').set_editable(True)
            #self.dialogtree.get_widget('entryDNS2').set_editable(True)
            dns = []
            f = open('/etc/resolv.conf', 'r')
            line = f.readline()
            while line:
                if line.startswith('nameserver'):
                    dns.append(line.split()[1].rstrip('\n'))
                line = f.readline()
            f.close()
            if len(dns) == 1:
                self.dialogtree.get_widget('entryDNS1').set_text(dns[0])
            elif len(dns) == 2:
                self.dialogtree.get_widget('entryDNS1').set_text(dns[0])
                self.dialogtree.get_widget('entryDNS2').set_text(dns[1])
        else:
            self.dialogtree.get_widget('radiobuttonAutoDNS').set_active(True)
            #self.dialogtree.get_widget('entryDNS1').set_editable(False)
            #self.dialogtree.get_widget('entryDNS2').set_editable(False)
        self.dialogtree.get_widget('entryServer').set_text(self.getvmUrl)
        self.setupwindow.show_all();

    def OnSaveConfig(self, widget):
        self.setupwindow.hide()
        f = open('/etc/network/interfaces', 'w')
        f.write('auto lo\n')
        f.write('iface lo inet loopback\n')
        f.write('auto eth0\n')
        if self.dialogtree.get_widget('radiobuttonDhcp').get_active():
            f.write('iface eth0 inet dhcp\n')
        else:
            f.write('iface eth0 inet static\n')
            f.write('address %s\n'%self.dialogtree.get_widget('entryDialogIP').get_text())
            f.write('netmask %s\n'%self.dialogtree.get_widget('entryDialogNetmask').get_text())
            f.write('gateway %s\n'%self.dialogtree.get_widget('entryDialogGateway').get_text())
        if self.dialogtree.get_widget('radiobuttonDNS').get_active():
            dns1 = self.dialogtree.get_widget('entryDNS1').get_text()
            if dns1:
                f.write('dns-nameserver %s\n'%dns1)
            dns2 = self.dialogtree.get_widget('entryDNS2').get_text()
            if dns2:
                f.write('dns-nameserver %s\n'%dns2)
        f.close()
        os.system('/etc/init.d/networking restart')
        self.alert('修改完成', '消息')
        #gtk.main_quit();

    def OnCancelConfig(self, widget):
        self.setupwindow.hide()
        #gtk.main_quit();

    def OnComboboxchanged(self, widget):
        index = self.comboVms.get_active()
        if index <= 0:
            return
        name, ip, port, passwd = self.vms[index]
        cmdline = 'spicec -f -h %s -p %s'%(ip, port)
        if passwd:
            cmdline += " -w %s"%passwd

        print cmdline
        ret = os.system(cmdline);
        if (ret != 0):
            self.alert("远程端口不能访问")

        self.comboVms.set_active(0)

    def OnClean(self, widget):
        self.entryuser.set_text('')
        self.entrypass.set_text('')
        self.comboVms.clear()
        self.comboVms.set_model(None)
        #self.toggleremember.set_active(False);

    def OnRemember(self, widget):
        if (self.toggleremember.get_active()):
            config = ConfigParser.RawConfigParser()
            config.add_section('login')
            config.set('login', 'user', self.entryuser.get_text())
            config.set('login', 'password', self.entrypass.get_text())
            config.set('login', 'graburl', self.getvmUrl)

            config.set('login', 'remember', self.toggleremember.get_active())

            # Writing our configuration file to 'example.cfg'
            with open(self.savedfilename, 'wb') as configfile:
                config.write(configfile)
        else:
            config = ConfigParser.RawConfigParser()
            config.add_section('login')
            config.set('login', 'user', '')
            config.set('login', 'password', '')
            config.set('login', 'graburl', self.getvmUrl)
            config.set('login', 'remember', self.toggleremember.get_active())

            # Writing our configuration file to 'example.cfg'
            with open(self.savedfilename, 'wb') as configfile:
                config.write(configfile)

    def OnRadiobuttonChanged(self, widget):
        self.dialogtree.get_widget('entryDialogIP').set_editable(
            self.dialogtree.get_widget('radiobuttonStaticIP').get_active())
        self.dialogtree.get_widget('entryDialogNetmask').set_editable(
            self.dialogtree.get_widget('radiobuttonStaticIP').get_active())
        self.dialogtree.get_widget('entryDialogGateway').set_editable(
            self.dialogtree.get_widget('radiobuttonStaticIP').get_active())
        self.dialogtree.get_widget('entryDNS1').set_editable(
            self.dialogtree.get_widget('radiobuttonDNS').get_active())
        self.dialogtree.get_widget('entryDNS2').set_editable(
            self.dialogtree.get_widget('radiobuttonDNS').get_active())

    def OnPageChanged(self, widget, point, pageindex):
        if pageindex == 1:
            ifconfigArea = self.dialogtree.get_widget('textviewIfconfig')
            p = Popen('ifconfig', stdout=PIPE, shell=True)
            p.wait()
            data = p.stdout.read()
            ifconfigArea.get_buffer().set_text(data)

    def OnTestPingClicked(self, widget):
        pingArea = self.dialogtree.get_widget('textviewPing')
        host = self.dialogtree.get_widget('pinghost').get_text()
        p = Popen('ping %s -c 4'%host, stdout=PIPE, shell=True)
        out, err = p.communicate()
        if err:
            pingArea.get_buffer().set_text(err)
        else:
            pingArea.get_buffer().set_text(out)

    def OnSaveServerClicked(self, widget):
        self.getvmUrl = self.dialogtree.get_widget('entryServer').get_text()
        config = ConfigParser.ConfigParser()
        config.read(self.savedfilename)
        if not config.has_section('login'):
            config.add_section('login')
        config.set('login', 'graburl', self.getvmUrl)
        # Writing our configuration file to 'example.cfg'
        with open(self.savedfilename, 'wb') as configfile:
            config.write(configfile)
        self.alert("修改完成", "消息")

    def alert(self, msg, title='警告'):
        dialog = gtk.Dialog(title, self.loginwindow, 0, (gtk.STOCK_OK, gtk.RESPONSE_OK))
        #dialog.set_default_size(250, 300)
        label = gtk.Label(msg);
        label1 = gtk.Label("");
        label2 = gtk.Label("");

        dialog.vbox.pack_start(label1, True, True, 0)
        dialog.vbox.pack_start(label, True, True, 0)
        dialog.vbox.pack_start(label2, True, True, 0)
        dialog.show_all()
        response = dialog.run()
        dialog.destroy()



if __name__ == "__main__":
    """
    mainWindow = gtk.Window();
    mainWindow.set_title("Login");
    mainWindow.connect("delete-event", gtk.main_quit)
    mainWindow.set_position(gtk.WIN_POS_CENTER)
    mainWindow.fullscreen()
    mainWindow.show_all();
    """

    login = LoginApp();
    gtk.main()



